#include "SimpleBody.h"
#include "Physics/Box2DWorld.h"

mtBEGIN(SimpleBody)
	mtBASE(ECS::Component);
	mtCONSTRUCTOR();
	mtMETHOD(onStart);
	mtMETHOD(onUpdate);
mtEND

SimpleBody::SimpleBody() :
	_body(nullptr)
{

}

SimpleBody::~SimpleBody()
{

}

void SimpleBody::onStart()
{
	auto b = _body;
	_tClient = getComponent<Transform>()->createClient([b](const ECS::Vec2<float>& pos, float ang) 
	{
		b->SetTransform(b2Vec2(pos.x, pos.y), ang);
	});
}

void SimpleBody::onUpdate()
{
	_tClient->setTransform(ECS::Vec2<float>(_body->GetPosition().x, _body->GetPosition().y), _body->GetAngle());
}

bool SimpleBody::initWith( SimpleBodyDef* def )
{
	b2BodyDef bodyDef;
	bodyDef.type = def->type;
	_body = Box2DWorld::getInstance()->getWorld()->CreateBody(&bodyDef);

	for (size_t i = 0; i < def->fixtures.size(); ++i)
	{
		const b2FixtureDef* f = def->fixtures.at(i);
		_body->CreateFixture(f);
	}

	_body->SetUserData(this);
	return true;
}

b2FixtureDef* SimpleBodyDef::addBox( float width, float height, float xcenter /*= 0.0f*/, float ycenter /*= 0.0f*/, float angle /*=0.0f*/ )
{
	b2FixtureDef* def = new b2FixtureDef();
	auto box = new b2PolygonShape();
	box->SetAsBox(width, height, b2Vec2(xcenter, ycenter), angle);
	def->shape = box;
	fixtures.push_back(def);

	return def;
}

b2FixtureDef* SimpleBodyDef::addCircle( float radius, float xcenter /*= 0.0f*/, float ycenter /*= 0.0f*/ )
{
	b2FixtureDef* def = new b2FixtureDef();
	auto circle = new b2CircleShape();
	circle->m_radius = radius;
	circle->m_p = b2Vec2(xcenter, ycenter);
	def->shape = circle;
	fixtures.push_back(def);
	
	return def;
}
